package com.gbas.muspulp;

import com.gbas.cartas.Carta;
import com.gbas.cartas.Constantes;
import com.gbas.model.Mazo;
import com.gbas.model.Naipe;
import pulpcore.Input;
import pulpcore.animation.Easing;
import pulpcore.animation.Timeline;
import pulpcore.animation.event.TimelineEvent;
import pulpcore.image.Colors;
import pulpcore.image.CoreFont;
import pulpcore.image.CoreImage;
import pulpcore.scene.Scene2D;
import pulpcore.sprite.Group;
import pulpcore.sprite.ImageSprite;
import pulpcore.sprite.Label;
import pulpcore.sprite.Sprite;

import java.util.HashSet;
import java.util.Set;

/**
 * User: t50
 * Date: 07-abr-2010
 * Time: 2:19:17
 */

public class PlayScene extends Scene2D {
    Mazo mazoReparto = new Mazo();
    //   Naipe comodin = new Naipe(VALOR.COMODIN, PALO.SINPALO);
    Carta cartaMazoReparto;
    Group cartasGroup[] = new Group[4];
    int jugadorMano;
    int maxoX, maxoY;
    int soyJugador;
    String nombres[] = {"Fidel", "JuanLuis", "Andres", "Jose Maria"};
    double posNombres[][] = {
            {150, 507, 1.0, 1.0},
            {630, 110, 1.0, 0.5},
            {492, 10, 0.0, 0.0},
            {10, 110, 0.0, 0.5},
    };
    TextMessage message;

    final Botonera botonera = new Botonera();
    CoreFont fontBlue = CoreFont.getSystemFont().tint(Colors.BLUE);
    CoreFont fontRed = CoreFont.getSystemFont().tint(Colors.RED);

    int conversionJugadores[][] = {
            {0, 1, 2, 3},
            {3, 0, 1, 2},
            {2, 3, 0, 1},
            {1, 2, 3, 0}
    };

    public int jugadorServer2Client(int jugadorServer) {
        return conversionJugadores[soyJugador][jugadorServer];
    }

    /**
     * Prepara la scena, fondos, graficos, etcetera.
     * 1. Carga las imagenes de los naipes y las almacena en el mapa
     */
    public void prepareGUI() {
        mazoReparto.generarTodasBreve();
        mazoReparto.mezcla();

        for (Naipe n : mazoReparto) {
            Carta.naipesMapa.put(n.nameOfImage(), CoreImage.load(n.nameOfImage()));
        }
        Carta.naipesMapa.put("back", CoreImage.load("x_back1.jpg"));
//        mazoReparto.addNaipe(reverso);

        cartaMazoReparto = new Carta(mazoReparto.peekNaipe(0), -200, -200);
        add(cartaMazoReparto);

        add(botonera);

        asignaNombres();
    }

    /**
     * Mueve el monton de reparto a la posicion inicial (posComienzo-1) y reparte 16 cartas
     * de una en una comenzando por posicion.
     *
     * @param tusCartas array de 4 cartas que te corresponden
     */
    public void haceRepartoInicial(Naipe[] tusCartas) {
        Timeline timelineMoveMazoReparto = new Timeline(Easing.BACK_IN);
        maxoX = Constantes.coordenadasMazo[Constantes.jAnterior(jugadorMano)][0];
        maxoY = Constantes.coordenadasMazo[Constantes.jAnterior(jugadorMano)][1];

        timelineMoveMazoReparto.moveTo(cartaMazoReparto,
                maxoX,
                maxoY,
                500
        );
        addTimeline(timelineMoveMazoReparto);

        for (int k = 0; k < 16; k++) {
            int jugador = (jugadorMano + k) & 3;

            final Carta cartaReparto = jugador != 0 ? new Carta(mazoReparto.peekNaipe(0), maxoX, maxoY)
                    : new Carta(tusCartas[k / 4], maxoX, maxoY);
            cartaReparto.setRotation(jugador);
            int dx = Constantes.coordenadasCartas[jugador][k / 4][0];
            int dy = Constantes.coordenadasCartas[jugador][k / 4][1];

            cartaReparto.moveTo(dx, dy, 1500, Easing.STRONG_IN_OUT, k * 450);

            if (jugador == 0) {
                Timeline timelineHijo2 = new Timeline(Easing.NONE);
                timelineHijo2.addEvent(new TimelineEvent(2200 + (k * 450)) {
                    @Override
                    public void run() {
                        cartaReparto.flip();
                    }
                });
                addTimeline(timelineHijo2);
                cartaReparto.setTag(tusCartas[k / 4]);
            }
            cartasGroup[jugador].add(cartaReparto);

        }
    }


    public void descartaDeJugador(int bitsCartas, int posJugador) {
        if (bitsCartas > 0) {
            int found = 0;
            for (int k = 0; k < 4; k++) {
                if ((bitsCartas & (1 << k)) > 0) {
                    final Carta sp = (Carta) cartasGroup[posJugador].get(k);

                    if (posJugador == 0) {
                        sp.flip();
                    }
                    sp.moveTo(maxoX, maxoY, 1500, Easing.STRONG_IN_OUT, found * 450);
                    found++;
                }
            }
        }
    }

    public void agregaCartas(int bitsCartas, int jugador, Naipe[] tusCartas) {
        if (bitsCartas > 0) {
            int found = 0;
            for (int k = 0; k < 4; k++) {
                if ((bitsCartas & (1 << k)) > 0) {

                    final Carta cartaReparto = jugador != 0 ? new Carta(mazoReparto.peekNaipe(0), maxoX, maxoY)
                            : new Carta(tusCartas[found], maxoX, maxoY);
                    int dx = Constantes.coordenadasCartas[jugador][k][0];
                    int dy = Constantes.coordenadasCartas[jugador][k][1];

                    cartaReparto.moveTo(dx, dy, 1500, Easing.STRONG_IN_OUT, found * 450);

                    cartasGroup[jugador].add(k, cartaReparto);

                    if (jugador == 0) {
                        Timeline timelineHijo2 = new Timeline(Easing.NONE);
                        timelineHijo2.addEvent(new TimelineEvent(1200 + (found * 450)) {
                            @Override
                            public void run() {
                                cartaReparto.flip();
                            }
                        });
                        addTimeline(timelineHijo2);

                    }
                    found++;
                }
            }
        }
    }

    public void muestraTodasLasCartas(Naipe[][] todasCartas) {
        for (int jugador = 1; jugador < 4; jugador++) {
            for (int carta = 0; carta < 4; carta++) {
                Carta ct = (Carta) cartasGroup[jugador].get(carta);
                ct.setNaipe(todasCartas[jugador][carta]);
                if (!ct.getMostrada())
                    ct.flip();
            }
        }
    }


    @Override
    public void load() {
        ImageSprite tapete = new ImageSprite(CoreImage.load("tapete.jpg"), 0, 0);
        add(tapete);

        message = new TextMessage(this);
        add(message);

        for (int k = 0; k < 4; k++) {
            Group gr = new Group();
            cartasGroup[k] = gr;
            add(gr);
        }

        prepareGUI();


        // Fase de pruebas

        final Naipe np[] = new Naipe[]{
                mazoReparto.getNaipe(),
                mazoReparto.getNaipe(),
                mazoReparto.getNaipe(),
                mazoReparto.getNaipe()
        };
        jugadorMano = 2;

        haceRepartoInicial(np);


        Timeline tm = new Timeline();
        tm.addEvent(new TimelineEvent(10000) {
            @Override
            public void run() {
                descartaDeJugador(3, jugadorMano);
            }
        });

        botonera.createBotonera(Botonera.TIPO_MUS);

        tm.addEvent(new TimelineEvent(3200) {
            @Override
            public void run() {
                botonera.createBotonera(Botonera.TIPO_APUESTA);
            }

        });

        tm.addEvent(new TimelineEvent(15000) {
            @Override
            public void run() {
                agregaCartas(3, jugadorMano, null);
            }
        });
        tm.addEvent(new TimelineEvent(20000) {
            @Override
            public void run() {
                descartaDeJugador(6, Constantes.jSiguiente(jugadorMano));
            }
        });
        tm.addEvent(new TimelineEvent(25000) {
            @Override
            public void run() {
                agregaCartas(6, Constantes.jSiguiente(jugadorMano), new Naipe[]{mazoReparto.getNaipe(), mazoReparto.getNaipe()});
            }
        });
        tm.addEvent(new TimelineEvent(30000) {
            @Override
            public void run() {
                Naipe naipess[][] = new Naipe[4][4];
                naipess[0] = np;
                naipess[1][0] = mazoReparto.getNaipe();
                naipess[1][1] = mazoReparto.getNaipe();
                naipess[1][2] = mazoReparto.getNaipe();
                naipess[1][3] = mazoReparto.getNaipe();
                naipess[2][0] = mazoReparto.getNaipe();
                naipess[2][1] = mazoReparto.getNaipe();
                naipess[2][2] = mazoReparto.getNaipe();
                naipess[2][3] = mazoReparto.getNaipe();
                naipess[3][0] = mazoReparto.getNaipe();
                naipess[3][1] = mazoReparto.getNaipe();
                naipess[3][2] = mazoReparto.getNaipe();
                naipess[3][3] = mazoReparto.getNaipe();
                muestraTodasLasCartas(naipess);
            }
        });
        addTimeline(tm);
        message.addMensajeTexto("Lorem ipsum dolor ", 1);
        message.addMensajeTexto("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur laoreet " +
                "augue quis turpis. In sem. Nam ac justo. Sed lacinia vulputate justo. Integer", 2);
        message.addMensajeTexto("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur laoreet " +
                "augue quis turpis. In sem. Nam ac justo. Sed lacinia vulputate justo. Integer " +
                "semper placerat enim. Proin fermentum feugiat augue. Sed placerat libero non ", 3);
        message.addMensajeTexto("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur laoreet " +
                "augue quis turpis. In sem. Nam ac justo. Sed lacinia vulputate justo. Integer " +
                "semper placerat enim. Proin fermentum feugiat augue. Sed placerat libero non ", 0);
        message.addMensajeTexto("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur laoreet " +
                "augue quis turpis. In sem. Nam ac justo. Sed lacinia vulputate justo. Integer", 2);
        message.addMensajeTexto("Lorem ipsum dolor sit amet, conse", 0);
        message.addMensajeTexto("Lorem ipsum it amet, conse", 0);
        message.addMensajeTexto("Lorem ipsum it amet, conse", 1);
        message.addMensajeTexto("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur laoreet " +
                "augue quis turpis. In sem. Nam ac justo. Sed lacinia vulputate justo. Integer", 2);
    }

    private void asignaNombres() {
        int count = 0;
        for (String n : nombres) {
            final Label label = new Label(count % 2 > 0 ? fontBlue : fontRed, n, posNombres[count][0], posNombres[count][1]);
            label.setAnchor(posNombres[count][2], posNombres[count][3]);
            add(label);
            count++;
        }
    }

    boolean momentoDescarte = true;
    Set<Naipe> selectedNaipes = new HashSet<Naipe>();

    @Override
    public void update(int elapsedTime) {
        super.update(elapsedTime);

        if (momentoDescarte) {

            if (Input.isMousePressed()) {
                Sprite sp = cartasGroup[0].pick(Input.getMouseX(), Input.getMouseY());
                if (sp != null) {
                    Naipe np = (Naipe) sp.getTag();

                    if (selectedNaipes.contains(np)) {
                        selectedNaipes.remove(np);
                        sp.alpha.animateTo(255, 500);
                    } else {
                        selectedNaipes.add(np);
                        sp.alpha.animateTo(64, 500);
                    }
                }
            }

        }
    }
}
